package com.enba.mallapi.module.goods.sku.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.enba.boot.core.base.Result;
import com.enba.mall.core.goods.es.EsGoodsDocument;
import com.enba.mall.core.goods.es.EsGoodsDocument.EsSkuListDoc;
import com.enba.mall.core.goods.sku.entity.Sku;
import com.enba.mall.core.goods.sku.handler.MallSearchHandler;
import com.enba.mall.core.goods.sku.handler.MallSearchHandler.MallSearchEnum;
import com.enba.mall.core.goods.sku.req.SearchGoodsReq;
import com.enba.mall.core.goods.spu.resp.ProductDetailResponse.SpecDetail;
import com.enba.mall.core.goods.spu.resp.ProductDetailResponse.SpecValue;
import com.enba.mall.core.utils.PageDataResp;
import com.enba.mallapi.annotation.NoNeedValidation;
import com.google.api.client.util.Lists;
import com.google.api.client.util.Sets;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@Api(tags = "商品搜索")
@RestController
@RequestMapping("/api/sku/search")
public class MallSearchController {

  @Value("${mall-sku.handler-key}")
  private MallSearchEnum handlerKey;

  @ApiOperation("商品详情")
  @GetMapping("/detail/{spuId}")
  @NoNeedValidation
  public Result<ProductDetailResp> detail(@PathVariable Long spuId) {
    EsGoodsDocument detailDoc = MallSearchHandler.getHandler(handlerKey).detail(spuId);

    // 转换出参
    ProductDetailResp resp = assembleDetailDoc(detailDoc);

    return Result.success(resp);
  }

  /**
   * 组装商品详情
   *
   * @param detailDoc 商品详情
   * @return 商品详情
   */
  private ProductDetailResp assembleDetailDoc(EsGoodsDocument detailDoc) {
    List<EsSkuListDoc> skuList = detailDoc.getSkuList();

    EsSkuListDoc doc = skuList.get(0);

    ProductDetailResp resp = new ProductDetailResp();
    resp.setId(detailDoc.getSpuId());
    resp.setTitle(detailDoc.getSpuName());
    resp.setDesc(detailDoc.getSpuDesc());
    resp.setOriginalPrice(doc.getOriginalPrice());
    resp.setPrice(doc.getSkuPrice());

    //  spu主图
    String headerPicUrl = detailDoc.getHeaderPicUrl();
    List<String> images = Lists.newArrayList();
    images.add(headerPicUrl);
    images.add("images/product2.png");
    images.add("images/product3.png");
    resp.setImages(images);

    // 规格参数组装
    assembleSpec(detailDoc, resp);

    // 详情介绍
    resp.setDetail(detailDoc.getSpuDesc());

    /**
     * 规格参数： [ { name: "品牌", value: "Apple" }, { name: "型号", value: "iPhone 15 Pro Max" }, {
     * name:"颜色", value: "暗紫色" }, { name: "容量", value: "128GB" } ]
     */
    List<Param> params = Lists.newArrayList();
    String str2 =
        "[ { name: \"品牌\", value: \"Apple\" }, { name: \"型号\", value: \"iPhone 15 Pro Max\" }, { name:\"颜色\", value: \"暗紫色\" }, { name: \"容量\", value: \"128GB\" } ]";
    params = JSON.parseArray(str2, Param.class);
    resp.setParams(params);

    // 存放属性值跟SKU的映射关系
    specSkuMap(skuList, resp);

    // sku列表
    resp.setSkuList(BeanUtil.copyToList(skuList, ProductSkuDetailResp.class));

    return resp;
  }

  private void specSkuMap(List<EsSkuListDoc> skuList, ProductDetailResp resp) {
    Map<String, Long> specValueIdMap = Maps.newHashMap();
    for (EsSkuListDoc sku : skuList) {
      Long skuId = sku.getSkuId();

      String valueIdStr =
          JSON.parseArray(sku.getSkuSpecEnums()).stream()
              .map(
                  o -> {
                    JSONObject o1 = (JSONObject) o;
                    return o1.getLong("valueId");
                  })
              .sorted()
              .map(String::valueOf)
              .collect(Collectors.joining(":"));
      specValueIdMap.put(valueIdStr, skuId);
    }
    resp.setSpecValueIdMap(specValueIdMap);
  }

  private void assembleSpec(EsGoodsDocument detailDoc, ProductDetailResp resp) {
    List<Option> options = Lists.newArrayList();
    List<SpecDetail> specList = detailDoc.getSpecList();
    for (SpecDetail specDetail : specList) {
      // 规格名称
      String specName = specDetail.getSpecName();
      // 规格值集合
      List<SpecValue> valueList = specDetail.getValues();

      Option option = new Option();
      option.setName(specName);

      Set<OptionItem> valueSet = Sets.newHashSet();
      for (SpecValue specValue : valueList) {
        OptionItem optionItem = new OptionItem();
        optionItem.setSpecValueId(specValue.getId() + "");
        optionItem.setSpecValueName(specValue.getSpecValue());
        valueSet.add(optionItem);
      }
      option.setValues(valueSet);

      // 添加到属性集合
      options.add(option);
    }
    resp.setOptions(options);
  }

  @Data
  public static class ProductDetailResp {

    @ApiModelProperty(value = "商品id-spuid")
    private Long id;

    @ApiModelProperty(value = "标题")
    private String title;

    @ApiModelProperty(value = "描述")
    private String desc;

    @ApiModelProperty(value = "原价")
    private BigDecimal originalPrice;

    @ApiModelProperty(value = "价格")
    private BigDecimal price;

    @ApiModelProperty(value = "图片")
    private List<String> images;

    // 属性集合
    @ApiModelProperty(value = "属性")
    private List<Option> options;

    // 详情介绍
    private String detail;

    @ApiModelProperty(value = "规格参数")
    private List<Param> params;

    @ApiModelProperty(value = "根据参数值SpecValueId找到对应规格skuId eg: 111:2222:33=>4444")
    private Map<String, Long> specValueIdMap;

    @ApiModelProperty(value = "sku列表")
    private List<ProductSkuDetailResp> skuList;
  }

  @Data
  public static class ProductSkuDetailResp {
    /** skuID */
    private Long skuId;

    /** sku编码 */
    private String skuCode;

    /** sku名称 */
    private String skuName;

    /** 最小购买量 */
    private Integer moq;

    /** 库存 */
    private Integer inventory;

    /** 单价 */
    private BigDecimal skuPrice;

    /** 原价 */
    private BigDecimal originalPrice;

    /** 规格 */
    private String skuSpecEnums;

    /** sku描述 */
    private String skuDesc;

    /** 是否生效（1生效中 0失效） */
    private Integer status;

    /** 销量 */
    private Integer sales;
  }

  @Data
  public static class Option {

    @ApiModelProperty(value = "属性名称")
    private String name;

    @ApiModelProperty(value = "属性值集合")
    private Set<OptionItem> values;
  }

  @Data
  public static class OptionItem {
    // 参数值id
    private String specValueId;
    // 参数值名称
    private String specValueName;
  }

  @Data
  public static class Param {

    @ApiModelProperty(value = "参数名称")
    private String name;

    @ApiModelProperty(value = "参数值")
    private String value;
  }

  @ApiOperation("商品搜索")
  @RequestMapping(value = "/list", method = RequestMethod.POST)
  @NoNeedValidation
  public Result<?> searchGoods(@RequestBody SearchGoodsReq req) {
    PageDataResp pageDataResp = MallSearchHandler.getHandler(handlerKey).searchGoods(req);

    // 转换数据
    transformData(pageDataResp);

    return Result.success(pageDataResp);
  }

  private void transformData(PageDataResp pageDataResp) {
    pageDataResp.transformData(
        data -> {
          List<EsGoodsDocument> esGoodsDocList =
              JSON.parseArray(JSON.toJSONString(data), EsGoodsDocument.class);

          // TODO DEL
          for (int i = 0; i < 9; i++) {
            esGoodsDocList.add(esGoodsDocList.get(0));
          }

          return esGoodsDocList.stream()
              .map(
                  esGoodsDocument -> {
                    // 取sku中最低价
                    List<EsSkuListDoc> skuList = esGoodsDocument.getSkuList();
                    EsSkuListDoc esSkuListDoc =
                        skuList.stream().min(Comparator.comparing(EsSkuListDoc::getSkuPrice)).get();

                    // count sales 总销量
                    int salesum = skuList.stream().mapToInt(EsSkuListDoc::getSales).sum();

                    ProductDataResp resp = new ProductDataResp();
                    // 商品id-spuid
                    resp.setId(esGoodsDocument.getSpuId());
                    // 标题
                    resp.setTitle(esGoodsDocument.getSpuName());
                    //  价格
                    resp.setPrice(esSkuListDoc.getSkuPrice());
                    // 原价
                    resp.setOriginalPrice(esSkuListDoc.getOriginalPrice());
                    //  图片
                    resp.setImage(esGoodsDocument.getHeaderPicUrl());
                    // 总销量
                    resp.setSales(salesum);
                    // 店铺
                    resp.setShop("恩爸商城");
                    return resp;
                  })
              .collect(Collectors.toList());
        });
  }

  @Data
  public static class ProductDataResp {

    @ApiModelProperty(value = "商品id-spuid")
    private Long id;

    @ApiModelProperty(value = "标题")
    private String title;

    @ApiModelProperty(value = "价格")
    private BigDecimal price;

    @ApiModelProperty(value = "原价")
    private BigDecimal originalPrice;

    @ApiModelProperty(value = "图片")
    private String image;

    @ApiModelProperty(value = "总销量-spu下所有sku销量之和")
    private long sales;

    @ApiModelProperty(value = "店铺")
    private String shop;
  }
}
